{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "8c22d429",
   "metadata": {},
   "source": [
    "## numpy的拷贝、深拷贝和浅拷贝\n",
    "视频讲解比较好，不明之处可再次观看。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b8a5089e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "760bbf29",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c1 = np.arange(10)\n",
    "c1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "302ee1f9",
   "metadata": {},
   "source": [
    "1. 不拷贝，下面这种情况两个变量指向一个数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "0cf071cc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7 8 9]\n",
      "********************\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "#下面的情况是简单的赋值，不进行拷贝。原来的栈区变量取了个别名。\n",
    "a = c1\n",
    "print(a)\n",
    "print('*'*20)\n",
    "print(a is c1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "69e34870",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "140281887750544\n",
      "140281887750544\n"
     ]
    }
   ],
   "source": [
    "print(id(a))\n",
    "print(id(c1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "52c5490c",
   "metadata": {},
   "source": [
    "2. 视图(View)或者浅拷贝，只在栈区拷贝了变量名至另外一个。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "18f3c51e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c2 = np.arange(12)\n",
    "c2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "ec3a6f1f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = c2.view()\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "4edf8a5c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "print(c2 is b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "cd573775",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[100   1   2   3   4   5   6   7   8   9  10  11]\n",
      "********************\n",
      "[100   1   2   3   4   5   6   7   8   9  10  11]\n"
     ]
    }
   ],
   "source": [
    "#这里验证view函数出现了深拷贝的特征????修改view后的数组，并没有改变原数组。\n",
    "b[0]=100\n",
    "print(c2)\n",
    "print('*'*20)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "a6dd01e2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "140281887925808\n",
      "140281887925136\n"
     ]
    }
   ],
   "source": [
    "print(id(c2))\n",
    "print(id(b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "cf6eb0d9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function id in module builtins:\n",
      "\n",
      "id(obj, /)\n",
      "    Return the identity of an object.\n",
      "    \n",
      "    This is guaranteed to be unique among simultaneously existing objects.\n",
      "    (CPython uses the object's memory address.)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(id)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6651979",
   "metadata": {},
   "source": [
    "3. 深拷贝。copy()函数，这里与python的深拷贝保持一致。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "c29be8c2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c3 = np.arange(11)\n",
    "c3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "0bef7248",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = c3.copy()\n",
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "792738f7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "print(c3 is d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "73e4a50c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0  1  2  3  4  5  6  7  8  9 10]\n",
      "********************\n",
      "[100   1   2   3   4   5   6   7   8   9  10]\n"
     ]
    }
   ],
   "source": [
    "d[0]=100\n",
    "print(c3)\n",
    "print('*'*20)\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "44f5a8ef",
   "metadata": {},
   "source": [
    "## 总结：\n",
    "在数组操作中分为三种\n",
    "1. 不拷贝: 只是在栈区将原来的变量重命名。\n",
    "2. 浅拷贝：只拷贝指定栈区，不拷贝堆区。修改浅拷贝会影响原有的数组。\n",
    "3. 深拷贝: 在堆区拷贝了一份新的数据。修改拷贝的数据后，不会影响原来的数组数据。\n",
    "* 概念理解(个人理解，并不准确)：\n",
    "* 栈区、和堆区出自C语言，只一种内存存储的方式。栈区存储的是变量名称相关内容，可以快速运算。堆区储存变量的真实数据，数据量较大，运算起来相对较慢。\n",
    "* 大部分的数据都有这几类拷贝的概念。针对数据的方法也存在深浅拷贝等不同方法。\n",
    "* 可以使用python中的id()函数，查看数据的原是记载地址。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
